home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / os_aix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  6.5 KB  |  294 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  */
  22.  
  23. /*
  24.  *   IBM AIX version 3.2.x and 4.x support
  25.  *
  26.  *   Contributing author: Kurt Brunton
  27.  *   E-Mail: kbrunton@ccd.harris.com
  28.  *
  29.  *   Contributing author: Tom Crawley
  30.  *   E-Mail: tomc@osi.curtin.edu.au
  31.  *
  32.  *   This software fragment contains code that interfaces the CD player
  33.  *   application to the IBM AIX operating system.  The name "IBM" is
  34.  *   used here for identification purposes only.
  35.  *
  36.  */
  37. #ifndef LINT
  38. static char *_os_aix_c_ident_ = "@(#)os_aix.c    5.6 94/12/28";
  39. #endif
  40.  
  41. #include "common.d/appenv.h"
  42. #include "common.d/util.h"
  43. #include "libdi.d/libdi.h"
  44. #include "libdi.d/scsipt.h"
  45.  
  46. #if defined(_AIX) && defined(DI_SCSIPT) && !defined(DEMO_ONLY)
  47.  
  48. extern appdata_t    app_data;
  49. extern bool_t        scsipt_notrom_error;
  50. extern FILE        *errfp;
  51.  
  52. STATIC int        pthru_fd = -1;    /* Passthrough device file desc */
  53.  
  54.  
  55. /*
  56.  * pthru_send
  57.  *    Build SCSI CDB and send command to the device.
  58.  *
  59.  * Args:
  60.  *    opcode - SCSI command opcode
  61.  *    addr - The "address" portion of the SCSI CDB
  62.  *    buf - Pointer to data buffer
  63.  *    size - Number of bytes to transfer
  64.  *    rsvd - The "reserved" portion of the SCSI CDB
  65.  *    length - The "length" portion of the SCSI CDB
  66.  *    param - The "param" portion of the SCSI CDB
  67.  *    control - The "control" portion of the SCSI CDB
  68.  *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  69.  *    prnerr - Whether an error message should be displayed
  70.  *         when a command fails
  71.  *
  72.  * Return:
  73.  *    TRUE - command completed successfully
  74.  *    FALSE - command failed
  75.  */
  76. bool_t
  77. pthru_send(
  78.     byte_t        opcode,
  79.     word32_t    addr,
  80.     byte_t        *buf,
  81.     word32_t    size,
  82.     byte_t        rsvd,
  83.     word32_t    length,
  84.     byte_t        param,
  85.     byte_t        control,
  86.     byte_t        rw,
  87.     bool_t        prnerr
  88. )
  89. {
  90.     struct sc_iocmd    sc_cmd;
  91.     int        kstat;
  92.  
  93.     if (pthru_fd < 0 || scsipt_notrom_error)
  94.         return FALSE;
  95.  
  96.     memset(&sc_cmd, 0, sizeof(sc_cmd));
  97.  
  98.     /* set up SCSI CDB */
  99.     switch (opcode & 0xf0) {
  100.     case 0xa0:
  101.     case 0xe0:
  102.         /* 12-byte commands */
  103.         sc_cmd.scsi_cdb[0] = opcode;
  104.         sc_cmd.scsi_cdb[1] = param;
  105.         sc_cmd.scsi_cdb[2] = (addr >> 24) & 0xff;
  106.         sc_cmd.scsi_cdb[3] = (addr >> 16) & 0xff;
  107.         sc_cmd.scsi_cdb[4] = (addr >> 8) & 0xff;
  108.         sc_cmd.scsi_cdb[5] = (addr & 0xff);
  109.         sc_cmd.scsi_cdb[6] = (length >> 24) & 0xff;
  110.         sc_cmd.scsi_cdb[7] = (length >> 16) & 0xff;
  111.         sc_cmd.scsi_cdb[8] = (length >> 8) & 0xff;
  112.         sc_cmd.scsi_cdb[9] = length & 0xff;
  113.         sc_cmd.scsi_cdb[10] = rsvd;
  114.         sc_cmd.scsi_cdb[11] = control;
  115.  
  116.         sc_cmd.command_length = 12;
  117.         break;
  118.  
  119.     case 0xc0:
  120.     case 0xd0:
  121.     case 0x20:
  122.     case 0x30:
  123.     case 0x40:
  124.         /* 10-byte commands */
  125.         sc_cmd.scsi_cdb[0] = opcode;
  126.         sc_cmd.scsi_cdb[1] = param;
  127.         sc_cmd.scsi_cdb[2] = (addr >> 24) & 0xff;
  128.         sc_cmd.scsi_cdb[3] = (addr >> 16) & 0xff;
  129.         sc_cmd.scsi_cdb[4] = (addr >> 8) & 0xff;
  130.         sc_cmd.scsi_cdb[5] = addr & 0xff;
  131.         sc_cmd.scsi_cdb[6] = rsvd;
  132.         sc_cmd.scsi_cdb[7] = (length >> 8) & 0xff;
  133.         sc_cmd.scsi_cdb[8] = length & 0xff;
  134.         sc_cmd.scsi_cdb[9] = control;
  135.  
  136.         sc_cmd.command_length = 10;
  137.         break;
  138.  
  139.     case 0x00:
  140.     case 0x10:
  141.         /* 6-byte commands */
  142.         sc_cmd.scsi_cdb[0] = opcode;
  143.         sc_cmd.scsi_cdb[1] = param;
  144.         sc_cmd.scsi_cdb[2] = (addr >> 8) & 0xff;
  145.         sc_cmd.scsi_cdb[3] = addr & 0xff;
  146.         sc_cmd.scsi_cdb[4] = length & 0xff;
  147.         sc_cmd.scsi_cdb[5] = control;
  148.  
  149.         sc_cmd.command_length = 6;
  150.         break;
  151.  
  152.     default:
  153.         if (app_data.scsierr_msg && prnerr)
  154.             fprintf(errfp, "0x%02x: Unknown SCSI opcode\n",
  155.                 opcode);
  156.         return FALSE;
  157.     }
  158.  
  159.     DBGDUMP("SCSI CDB bytes", (byte_t *) sc_cmd.scsi_cdb,
  160.         sc_cmd.command_length);
  161.  
  162.     /* set up sc_iocmd */
  163.     sc_cmd.buffer = (caddr_t) buf;
  164.     sc_cmd.data_length = (int) size;
  165.     sc_cmd.timeout_value = 5;    /* Allow 5 seconds */
  166.  
  167.     sc_cmd.flags = SC_ASYNC; 
  168.     if (size != 0)
  169.         sc_cmd.flags |= (rw == READ_OP) ? B_READ : B_WRITE;
  170.  
  171.     /* Send the command down via the "pass-through" interface */
  172.     if ((kstat = ioctl(pthru_fd, CDIOCMD, &sc_cmd)) < 0) {
  173.         if (app_data.scsierr_msg && prnerr)
  174.             perror("CDIOCMD ioctl failed");
  175.  
  176.         return FALSE;
  177.     }
  178.  
  179.     if ((sc_cmd.status_validity & 0x01) != 0) {
  180.         if (sc_cmd.scsi_bus_status != SC_GOOD_STATUS) {
  181.             if (app_data.scsierr_msg && prnerr) {
  182.                 fprintf(errfp,
  183.                     "CD audio: %s %s:\n%s=0x%x %s=0x%x\n",
  184.                     "SCSI bus status error on",
  185.                     app_data.device,
  186.                     "Opcode",
  187.                     opcode,
  188.                     "Status",
  189.                     sc_cmd.scsi_bus_status);
  190.             }
  191.         }
  192.  
  193.         return FALSE;
  194.     }
  195.     
  196.     if ((sc_cmd.status_validity & 0x02) != 0) {
  197.         if (sc_cmd.adapter_status != SC_GOOD_STATUS) {
  198.             if (app_data.scsierr_msg && prnerr) {
  199.                 fprintf(errfp,
  200.                     "CD audio: %s %s:\n%s=0x%x %s=0x%x\n",
  201.                     "adapter status error on",
  202.                     app_data.device,
  203.                     "Opcode",
  204.                     opcode,
  205.                     "Status",
  206.                     sc_cmd.adapter_status);
  207.             }
  208.         }
  209.  
  210.         return FALSE;
  211.     }
  212.  
  213.     return TRUE;
  214. }
  215.  
  216.  
  217. /*
  218.  * pthru_open
  219.  *    Open SCSI pass-through device
  220.  *
  221.  * Args:
  222.  *    path - device path name string
  223.  *
  224.  * Return:
  225.  *    TRUE - open successful
  226.  *    FALSE - open failed
  227.  */
  228. bool_t
  229. pthru_open(char *path)
  230. {
  231.     struct stat    stbuf;
  232.     char        errstr[ERR_BUF_SZ];
  233.  
  234.     /* Check for validity of device node */
  235.     if (stat(path, &stbuf) < 0) {
  236.         sprintf(errstr, app_data.str_staterr, path);
  237.         cd_fatal_popup(app_data.str_fatal, errstr);
  238.         return FALSE;
  239.     }
  240.  
  241.     if (!S_ISCHR(stbuf.st_mode)) {
  242.         sprintf(errstr, app_data.str_noderr, path);
  243.         cd_fatal_popup(app_data.str_fatal, errstr);
  244.         return FALSE;
  245.     }
  246.  
  247.     if ((pthru_fd = openx(path, O_RDONLY, NULL, SC_DIAGNOSTIC)) < 0) {
  248.         DBGPRN(errfp, "Cannot open %s: errno=%d\n", path, errno);
  249.         return FALSE;
  250.     }
  251.  
  252.     return TRUE;
  253. }
  254.  
  255.  
  256. /*
  257.  * pthru_close
  258.  *    Close SCSI pass-through device
  259.  *
  260.  * Args:
  261.  *    Nothing.
  262.  *
  263.  * Return:
  264.  *    Nothing.
  265.  */
  266. void
  267. pthru_close(void)
  268. {
  269.     if (pthru_fd >= 0) {
  270.         close(pthru_fd);
  271.         pthru_fd = -1;
  272.     }
  273. }
  274.  
  275.  
  276. /*
  277.  * pthru_vers
  278.  *    Return OS Interface Module version string
  279.  *
  280.  * Args:
  281.  *    Nothing.
  282.  *
  283.  * Return:
  284.  *    Module version text string.
  285.  */
  286. char *
  287. pthru_vers(void)
  288. {
  289.     return ("OS Interface module (for IBM AIX 3.2.x and 4.x)\n");
  290. }
  291.  
  292. #endif    /* _AIX DI_SCSIPT DEMO_ONLY */
  293.  
  294.